#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <netinet/in.h>

int main(int argc, char **argv) {
	int sockfd, newsockfd, portno, clilen;
	char buffer[256];
	struct sockaddr_in serv_addr, cli_addr;
	int n;


	// int socket (int family, int type, int protocol);
	// protocol: 0 to select the system's default for the given combination of family and type
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0) {
		perror("ERROR opening socket");
		exit(1);
	}

	// init socket structure
	bzero((char *)&serv_addr, sizeof(serv_addr));
	portno = 5001;

	serv_addr.sin_family = AF_INET;
	// INADDR_ANY 指定地址为0.0.0.0的地址，表示“任意地址”。 cat /usr/include/netinet/in.h | grep INADDR_ANY
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(portno);

	// bind
	if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
		perror("ERROR on binding");
		exit(1);
	}

	// start listen
	listen(sockfd, 5);
	clilen = sizeof(cli_addr);
	while (1) {
		newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
		printf("accept returns\n");
		if (newsockfd < 0) {
			perror("ERROR on accept");
			exit(1);
		}

		// create child process
		int pid = fork();
		if (pid < 0) {
			perror("ERROR on fork");
			exit(1);
		}
		if (pid == 0) { // child
			printf("child process\n");
			close(sockfd);
			doprocessing(newsockfd);
			exit(0);
		} else {
			close(newsockfd);
		}
	}
}

void doprocessing (int sock) {
	int n;
	char buffer[256];
	bzero(buffer, 256);
	n = read(sock, buffer, 255);
	if (n < 0)	{
		perror("ERROR reading from socket");
		exit(1);
	}

	printf("Here is the message: %s\n", buffer);
	n = write(sock, "I got your message", 18);

	if (n < 0){
		perror("ERROR writing to socket");
		exit(1);
	}
}